OPC Studio User's Guide and Reference
OPC UA Node Registration Service
Client and Subscriber Development > Features > Services > OPC UA Node Registration Service

Node registration is a mechanism that can improve performance with repeatedly accessed nodes. Your code can specify the nodes it plans to access, and doing so allows the server to prepare for that. The subsequent access (such as reading, writing, or method calls) to the registered nodes can then proceed in a more efficient manner.

The use of node registration is optional, and it does not influence the semantics of the program (i.e. the results you obtain - leaving aside the efficiency gain, and changes caused by different timing).

The features discussed here, or some of them, may not be available in all editions of the product. Check the Product Editions page for differences between the editions. The trial license has all features enabled (and is limited in period for which it provides valid data), but licenses for specific commercial editions may have functionality limitations.

In OPC UA, you can register the nodes using the IEasyUAClientNodeRegistration service that you obtain from the EasyUAClient component.

By registering a node using the IEasyUAClientNodeRegistration Interface, you declare a permanent intent for the node to be registered while the conection to the target server is open, until you specifically perform the node unregistration using the registration handle obtain (which becomes invalid at that point). From the functional point of view, it is irrelevant whether the connection to the server is open at the time of RegisterMultipleNodes Method call, or not. If it is open, QuickOPC will perform the registration with the server at that time. If it is not open, QuickOPC will perform the registration as part of the preocess of opening the connection.

Besides usage errors (invalid arguments), the RegisterMultipleNodes Method and UnregisterMultipleNodes Method (and derived extension methods) do not report any other errors. If the node registration fails for whatever reason, the nodes will simply remain unregistered, but the program will continue to function normally. The common reasons for the node registration to fail might be that the OPC UA server does not support node registration, or (when it supports it) the particular node(s) that you are trying to register are not suitable for registration, or that a server has already reached its internal limit on how many nodes can be registered per session or globally. Consult the documentation of your OPC UA server to find out details about how it handles the node registration.

In some cases, it might be beneficial to combine the use of the node registration service with the Operation Control Services, and explicitly lock the connection to the target OPC server so that the components attempts to keep it open for some duration. There are two basic reasons to do that:

// This example shows how to register and unregister multiple nodes in an OPC UA server, and use this approach together with
// connection locking.
//
// Node registration (with OPC UA servers that support it) can improve performance with repeatedly accessed nodes.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using Microsoft.Extensions.DependencyInjection;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;
using OpcLabs.EasyOpc.UA.Services;
using OpcLabs.EasyOpc.UA.Services.Extensions;

namespace UADocExamples._EasyUAClientNodeRegistration
{
    class RegisterAndUnregisterMultipleNodes
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Instantiate the client object.
            using (var client = new EasyUAClient())
            {
                // Obtain the client node registration service.
                IEasyUAClientNodeRegistration clientNodeRegistration = client.GetRequiredService<IEasyUAClientNodeRegistration>();

                // Obtain the client connection control service.
                IEasyUAClientConnectionControl clientConnectionControl = client.GetRequiredService<IEasyUAClientConnectionControl>();

                var nodeDescriptorArray = new UANodeDescriptor[]
                {
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[0]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[4]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[8]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[12]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[16]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[20]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[24]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[28]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[32]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[36]"
                };

                Console.WriteLine("Registering nodes");
                int[] registrationHandleArray = clientNodeRegistration.RegisterMultipleNodes(endpointDescriptor, nodeDescriptorArray);

                Console.WriteLine("Locking the connection");
                // Locking the connection will attempt to open it, and when successful, the nodes will be registered with
                // the server at that time. The use of locking is not necessary, but it may bring benefits together with the
                // node registration. See the conceptual documentation for more information.
                int lockHandle = clientConnectionControl.LockConnection(endpointDescriptor);

                Console.WriteLine("Waiting for 10 seconds...");
                // The example uses this delay to demonstrate the fact that your code might have other tasks to do, before
                // it accesses the previously registered nodes.
                System.Threading.Thread.Sleep(10 * 1000);

                Console.WriteLine("Reading (1)");
                UAAttributeDataResult[] resultArray1 = client.ReadMultiple(endpointDescriptor, nodeDescriptorArray);
                foreach (UAAttributeDataResult result in resultArray1)
                    Console.WriteLine(result);

                Console.WriteLine("Reading (2)");
                UAAttributeDataResult[] resultArray2 = client.ReadMultiple(endpointDescriptor, nodeDescriptorArray);
                foreach (UAAttributeDataResult result in resultArray2)
                    Console.WriteLine(result);

                Console.WriteLine("Unlocking the connection");
                clientConnectionControl.UnlockConnection(lockHandle);

                Console.WriteLine("Unregistering nodes");
                clientNodeRegistration.UnregisterMultipleNodes(registrationHandleArray);

                Console.WriteLine("Finished.");
            }
        }
    }
}
# This example shows how to register and unregister multiple nodes in an OPC UA server, and use this approach together
# with connection locking.
#
# Node registration (with OPC UA servers that support it) can improve performance with repeatedly accessed nodes.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from Microsoft.Extensions.DependencyInjection import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
from OpcLabs.EasyOpc.UA.Services import *
from OpcLabs.EasyOpc.UA.Services.Extensions import *


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Instantiate the client object.
client = None
try:
    client = EasyUAClient()

    # Obtain the client connection monitoring service.
    clientNodeRegistration = ServiceProviderServiceExtensions.GetRequiredService[IEasyUAClientNodeRegistration](client)
    if clientNodeRegistration is None:
        print('The client connection monitoring service is not available.')
        exit()

    # Obtain the client connection control service.
    clientConnectionControl = ServiceProviderServiceExtensions.GetRequiredService[IEasyUAClientConnectionControl](client)
    if clientConnectionControl is None:
        print('The client connection control service is not available.')
        exit()

    nodeDescriptorArray = [
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[0]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[4]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[8]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[12]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[16]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[20]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[24]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[28]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[32]'),
        UANodeDescriptor('nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[36]'),
    ]

    print('Registering nodes')
    registrationHandleArray = IEasyUAClientNodeRegistrationExtension.RegisterMultipleNodes(clientNodeRegistration,
                                                                                           endpointDescriptor,
                                                                                           nodeDescriptorArray)

    print('Locking the connection')
    # Locking the connection will attempt to open it, and when successful, the nodes will be registered with
    # the server at that time. The use of locking is not necessary, but it may bring benefits together with the
    # node registration. See the conceptual documentation for more information.
    lockHandle = clientConnectionControl.LockConnection(endpointDescriptor)

    print('Waiting for 10 seconds...')
    # The example uses this delay to demonstrate the fact that your code might have other tasks to do, before
    # it accesses the previously registered nodes.
    time.sleep(10)

    print('Reading (1)')
    attributeDataResultArray1 = IEasyUAClientExtension.ReadMultiple(client, endpointDescriptor, nodeDescriptorArray)
    for attributeDataResult in attributeDataResultArray1:
        print(attributeDataResult)

    print('Reading (2)')
    attributeDataResultArray2 = IEasyUAClientExtension.ReadMultiple(client, endpointDescriptor, nodeDescriptorArray)
    for attributeDataResult in attributeDataResultArray2:
        print(attributeDataResult)

    print('Unlocking the connection')
    clientConnectionControl.UnlockConnection(lockHandle)

    print('Unregistering nodes')
    clientNodeRegistration.UnregisterMultipleNodes(registrationHandleArray)

    print('Finished.')

finally:
    client and client.Dispose()
' This example shows how to register and unregister multiple nodes in an OPC UA server, and use this approach together with
' connection locking.
'
' Node registration (with OPC UA servers that support it) can improve performance with repeatedly accessed nodes.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports Microsoft.Extensions.DependencyInjection
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Imports OpcLabs.EasyOpc.UA.Services
Imports OpcLabs.EasyOpc.UA.Services.Extensions

Namespace _EasyUAClientNodeRegistration
    Friend Class RegisterAndUnregisterMultipleNodes
        Public Shared Sub Main1()
            Dim endpointDescriptor As UAEndpointDescriptor =
                    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            ' Instantiate the client.
            Using client = New EasyUAClient()
                ' Obtain the client node registration service.
                Dim clientNodeRegistration As IEasyUAClientNodeRegistration = client.GetRequiredService(Of IEasyUAClientNodeRegistration)

                ' Obtain the client connection control service.
                Dim clientConnectionControl As IEasyUAClientConnectionControl = client.GetRequiredService(Of IEasyUAClientConnectionControl)

                Dim nodeDescriptorArray = New UANodeDescriptor() {
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[0]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[4]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[8]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[12]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[16]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[20]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[24]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[28]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[32]",
                    "nsu=http://samples.org/UA/memorybuffer/Instance ;ns=8;s=UInt32[36]"
                }

                Console.WriteLine("Registering nodes")
                Dim registrationHandleArray() As Integer = clientNodeRegistration.RegisterMultipleNodes(endpointDescriptor, nodeDescriptorArray)

                Console.WriteLine("Locking the connection")
                ' Locking the connection will attempt to open it, and when successful, the nodes will be registered with
                ' the server at that time. The use of locking is not necessary, but it may bring benefits together with the
                ' node registration. See the conceptual documentation for more information.
                Dim lockHandle As Integer = clientConnectionControl.LockConnection(endpointDescriptor)

                Console.WriteLine("Waiting for 10 seconds...")
                ' The example uses this delay to demonstrate the fact that your code might have other tasks to do, before
                ' it accesses the previously registered nodes.
                System.Threading.Thread.Sleep(10 * 1000)

                Console.WriteLine("Reading (1)")
                Dim resultArray1() As UAAttributeDataResult = client.ReadMultiple(endpointDescriptor, nodeDescriptorArray)
                For Each result As UAAttributeDataResult In resultArray1
                    Console.WriteLine(result)
                Next result

                Console.WriteLine("Reading (2)")
                Dim resultArray2() As UAAttributeDataResult = client.ReadMultiple(endpointDescriptor, nodeDescriptorArray)
                For Each result As UAAttributeDataResult In resultArray2
                    Console.WriteLine(result)
                Next result

                Console.WriteLine("Unlocking the connection")
                clientConnectionControl.UnlockConnection(lockHandle)

                Console.WriteLine("Unregistering nodes")
                clientNodeRegistration.UnregisterMultipleNodes(registrationHandleArray)

                Console.WriteLine("Finished.")
            End Using
        End Sub
    End Class
End Namespace

 

You can study the OPC UA specifications (Part 4 - Services) to obtain more information about the node registration. Keep in mind, however, that although the methods provided by the IEasyUAClientNodeRegistration Interface look similar to and ultimately end up calling the RegisterNodes and UnregisterNodes services in OPC UA, there are important and crucial differences between the functionality of the OPC UA services, and the approach taken by the IEasyUAClientNodeRegistration Interface. Specifically:

In .NET, there are also extensions methods on the IEasyUAClientNodeRegistration Interface, provided by the IEasyUAClientNodeRegistrationExtension Class. In COM, some of these methods are directly accessible on the _EasyUAClientNodeRegistration Interface. You can, for example, easily register or unregister just one node, using the RegisterNode Method and UnregisterNode Method, and there are also methods that provide additional useful overloads to other methods. Note that for performance, if you have more nodes to register or unregister, it is strongly recommended to use RegisterMultipleNodes Method and UnregisterMultipleNodes Method, instead of repeatedly calling the methods that register or unregister a single node.

See Also

Reference

Examples - OPC UA Services

Web

Examples - OPC UA Specialized